<?php
/**
 * Copyright (c) 2018-2019.
 *  This file is part of the moonpie production
 *  (c) johnzhang <875010341@qq.com>
 *  This source file is subject to the MIT license that is bundled
 *  with this source code in the file LICENSE.
 */

namespace moonpie\plugin\wechat_account\model;


use app\common\model\BaseModel;
use EasyWeChat\Kernel\Support\Arr;
use moonpie\plugin\wechat_account\service\user\WechatUserInterface;
use moonpie\plugin\wechat_account\validate\WechatTemplateConfigValidator;
use think\Cache;

/**
 * 定义模型用来代表配置模板消息服务的模型
 * Class WechatTemplateConfig
 * @package moonpie\plugin\wechat_account\model
 */
class WechatTemplateConfig extends BaseModel
{
    const CACHE_KEY_TEMPLATE = 'wechat_account:template-config:%s';
    protected $type = ['template_data' => 'array'];
    protected $readonly = ['code'];
    private $_parser;

    public function getStatusAttr($status)
    {
        static $map = [
            0 => '禁用', 1 => '启用',
        ];
        return Arr::get($map, $status, '未知状态');
    }

    public function getValidator()
    {
        $validator = new WechatTemplateConfigValidator();
        if ($this->isUpdate) {
            $validator->useForUpdate($this->getId());
        }
        return $validator;
    }

    public function saveRecord(array $data)
    {
        $result = false !== $this->save($data);
        if (!$result) {
            $this->error = '保存数据出现错误';
            return false;
        }
        return true;
    }

    public function belongAccount()
    {
        return $this->belongsTo(WechatAccount::class, 'account_id', 'id');
    }

    /**
     * 发送消息给指定的用户
     * @param WechatUserInterface $user
     * @return boolean
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     */
    public function sendMessage(WechatUserInterface $user)
    {
        $model = new TemplateModel($this->belongAccount);
        $template = $model->findByTmplId($this->getData('template_id'));
        if (!$template) {
            $this->error = '没有找到指定的模板信息';
            return false;
        }
        $template = Arr::first($template);
        $model->setParser($this->getParser());
        $response = $model->sendTemplate($user, $template, $this->template_data);
        if (($errcode = Arr::get($response, 'errcode', 100)) !== 0) {
            $this->error = sprintf('发送模板消息出现错误，微信返回:code(%s),message(%s).', $errcode, Arr::get($response, 'errmsg', '微信返回未知错误'));
            return false;
        }
        return true;
    }

    public function getParser()
    {
        if (is_null($this->_parser)) {
            $container = app(true);
            $id = $this->getData('template_parser');
            if (isset($container[$id])) {
                return $this->_parser = $container[$id];
            }
            return $this->_parser = null;
        }
        return $this->_parser;
    }

    /**
     * @param $code
     * @param WechatAccount|null $account
     * @param bool $useCache
     * @return false|static
     */
    public static function loadByCode($code, WechatAccount $account = null, $useCache = true)
    {
        $cache_name = sprintf(static::CACHE_KEY_TEMPLATE, $code);
        $query = static::where('code', $code);
        if ($useCache) {
            $query->cache($cache_name);
        }
        $cache = $query->find();
        if (!$cache) {
            return false;
        }
        if ($cache->getData('status') == 0) return false;
        if ($account) {
            if ($account->getId() != $cache['account_id']) return false;
        }
        return $cache;
    }

    public static function init()
    {
        parent::init();
        static::afterWrite(function ($item) {
            $cache_name = sprintf(static::CACHE_KEY_TEMPLATE, $item['code']);
            if (Cache::has($cache_name)) {
                Cache::rm($cache_name);
            }
        });
    }
}